//
//  LBScoreView.m
//  Pods
//
//  Created by luckyRoy on 2017/8/29.
//
//

@interface LBScoreViewFrameModel : NSObject

@property (assign, nonatomic) CGFloat minX;

@property (assign, nonatomic) CGFloat maxX;

@property (assign, nonatomic) NSInteger starNum;

@end

#import "LBScoreView.h"

static NSInteger const LBScoreViewMaxStarNum = 5;

static CGFloat const LBScoreViewViewSpace = 5;

@class LBScoreViewFrameModel;

@interface LBScoreView ()

@property (copy, nonatomic) LBScoreViewComplete complete;

@property (strong, nonatomic) UIView *unSelectedView;

@property (strong, nonatomic) UIView *selectedView;

@property (assign, nonatomic) BOOL isSupportFloat;//default NO

@property (strong, nonatomic) NSMutableArray *starFrameArray;

@property (nonatomic, assign) BOOL isShowBigStar;//default NO show small star

@property (nonatomic, assign) LBScoreViewStarType starType;

@end

@implementation LBScoreView

- (instancetype)initWithOrigin:(CGPoint)origin
                isSupportFloat:(BOOL)isSupport
                      isEditor:(BOOL)isEdiotr
                      starType:(LBScoreViewStarType)starType
                      complete:(LBScoreViewComplete)complete
{
    CGRect newRect = self.frame;
    newRect.size = [self.class sizeOfViewByStarType:starType];
    newRect.origin = origin;
    self = [super initWithFrame:newRect];
    if (self) {
        self.isSupportFloat = isSupport;
        self.isEditor = isEdiotr;
        self.complete = complete;
        self.starType = starType;
        [self createAllView];
    }
    return self;
}

- (void)createAllView
{
    [self addSubview:self.selectedView];
    [self addSubview:self.unSelectedView];
    
    [self.selectedView setFrame:self.bounds];
    [self.unSelectedView setFrame:self.bounds];
    
    for (NSInteger i = 0; i < LBScoreViewMaxStarNum; i++) {
        
        UIImageView *starView = [self createImageViewByState:YES];
        
        [self.selectedView addSubview:starView];
        
        CGRect newRect = starView.frame;
        
        newRect.origin.x += i * (CGRectGetWidth(starView.frame) + LBScoreViewViewSpace);
        
        starView.frame = newRect;
        
        LBScoreViewFrameModel *model = [[LBScoreViewFrameModel alloc]init];
        model.minX = CGRectGetMinX(starView.frame);
        model.maxX = CGRectGetMaxX(starView.frame);
        model.starNum = (i + 1);
        [self.starFrameArray addObject:model];
    }

    for (NSInteger i = (LBScoreViewMaxStarNum - 1); i >= 0 ; i--) {
        
        UIImageView *starView = [self createImageViewByState:NO];
        
        [self.unSelectedView addSubview:starView];
        
        CGRect newRect = starView.frame;
        
        newRect.origin.x += i * (CGRectGetWidth(starView.frame) + LBScoreViewViewSpace);
        
        starView.frame = newRect;
        
        starView.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin;
        
    }
}

#pragma mark - translation

- (void)transLationToRealFrame:(CGFloat)xPoint
{
    __block CGFloat newPoint = xPoint;
    __block LBScoreViewFrameModel *lastModel = nil;
    if (self.isSupportFloat) {
        newPoint = xPoint;
    } else {
        [self.starFrameArray enumerateObjectsUsingBlock:^(LBScoreViewFrameModel *model, NSUInteger idx, BOOL * _Nonnull stop) {
            if (xPoint <= model.maxX &&
                xPoint >= model.minX) {
                newPoint = model.maxX;
            } else if (xPoint > lastModel.maxX &&
                       xPoint < model.minX) {
                newPoint = lastModel.maxX;
            }
            lastModel = model;
        }];
    }

    [self refreshUIByX:newPoint animation:YES isDelay:NO];
}

- (void)transLationPointToScoreNum:(CGFloat)xPoint
{
    __block LBScoreViewFrameModel *lastModel = nil;
    __block CGFloat scoreNum = 0;
    CGFloat oneStarWidth = [self.class sizeOfstarByStarType:self.starType].width;
    [self.starFrameArray enumerateObjectsUsingBlock:^(LBScoreViewFrameModel *model, NSUInteger idx, BOOL * _Nonnull stop) {
        if (xPoint <= model.maxX &&
            xPoint >= model.minX) {
            if (self.isSupportFloat) {
                scoreNum += idx;
                CGFloat space = (xPoint - model.minX);
                scoreNum += space / oneStarWidth;
                *stop = YES;
            } else {
                scoreNum += (idx + 1);
            }
        } else if (xPoint > lastModel.maxX &&
                   xPoint < model.minX) {
            scoreNum += idx;
            *stop = YES;
        }
        lastModel = model;
    }];
    if (self.complete) {
        self.complete(scoreNum);
    }
}

- (void)transLationScoreToPoint:(CGFloat)scoreNum animation:(BOOL)animation
{
    __block CGFloat newPoint = 0;
    CGFloat oneStarWidth = [self.class sizeOfstarByStarType:self.starType].width;
    [self.starFrameArray enumerateObjectsUsingBlock:^(LBScoreViewFrameModel *model, NSUInteger idx, BOOL * _Nonnull stop) {
        if (scoreNum >= model.starNum) {
            CGFloat space = (scoreNum - model.starNum) * oneStarWidth;
            if (self.isSupportFloat) {
                newPoint = model.maxX + space;
            } else {
                newPoint = model.maxX;
            }
        } else {
            CGFloat space = (model.starNum - scoreNum) * oneStarWidth;
            if (self.isSupportFloat) {
                newPoint = model.maxX - space;
            } else {
                newPoint = model.minX;
            }
            *stop = YES;
        }
    }];
    [self refreshUIByX:newPoint animation:animation isDelay:YES];
}

#pragma mark - refreshUI

- (void)refreshUIByX:(CGFloat)newX animation:(BOOL)animation isDelay:(BOOL)isDelay
{
    CGFloat animationTime = 0.25;
    CGFloat delay = 0;
    if (isDelay) {
        delay = 0.5;
    }
    if (animation) {
        [UIView animateWithDuration:animationTime delay:delay options:UIViewAnimationOptionCurveEaseInOut animations:^{
            CGRect newRect = self.unSelectedView.frame;
            newRect.size.width = ([self.class sizeOfViewByStarType:self.starType].width - newX);
            newRect.origin.x = newX;
            self.unSelectedView.frame = newRect;
        } completion:^(BOOL finished) {
        }];
    } else {
        CGRect newRect = self.unSelectedView.frame;
        newRect.size.width = ([self.class sizeOfViewByStarType:self.starType].width - newX);
        newRect.origin.x = newX;
        self.unSelectedView.frame = newRect;
    }
}

#pragma mark - clickAction

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
    if (self.isEditor) {
        UITouch *theTouch = [touches anyObject];
        CGPoint touchPoint = [theTouch locationInView:self];
        [self transLationToRealFrame:touchPoint.x];
        [self transLationPointToScoreNum:touchPoint.x];
    }
}

#pragma mark - setter

- (void)setScore:(CGFloat)scoreCount animation:(BOOL)animation
{
    if (scoreCount > LBScoreViewMaxStarNum) {
        scoreCount = LBScoreViewMaxStarNum;
    }
    [self transLationScoreToPoint:scoreCount animation:animation];
}

#pragma mark - getter

- (UIView *)selectedView
{
    if (!_selectedView) {
        _selectedView = [[UIView alloc]init];
        _selectedView.backgroundColor = [UIColor whiteColor];
    }
    return _selectedView;
}

- (UIView *)unSelectedView
{
    if (!_unSelectedView) {
        _unSelectedView = [[UIView alloc]init];
        [_unSelectedView.layer setMasksToBounds:YES];
        _unSelectedView.backgroundColor = [UIColor whiteColor];
    }
    return _unSelectedView;
}

- (NSMutableArray *)starFrameArray
{
    if (!_starFrameArray) {
        _starFrameArray = [[NSMutableArray alloc]init];
    }
    return _starFrameArray;
}

- (UIImage *)imageByState:(BOOL)isSelected starType:(LBScoreViewStarType)starType
{
    NSString *imageName;
    
    switch (starType) {
        case LBScoreViewStarTypeSmall:
        {
            if (isSelected) {
                imageName = @"lb_score_selected_star_small";
            } else {
                imageName = @"lb_score_unselected_star_small";
            }
        }
            break;
        case LBScoreViewStarTypeMiddle:
        {
            if (isSelected) {
                imageName = @"lb_score_selected_star_middle";
            } else {
                imageName = @"lb_score_unselected_star_middle";
            }
        }
            break;
        case LBScoreViewStarTypeBig:
        {
            if (isSelected) {
                imageName = @"lb_score_selected_star_big";
            } else {
                imageName = @"lb_score_unselected_star_big";
            }
        }
            break;
            
        default:
            break;
    }

    return [UIImage imageNamed:imageName];
}

- (UIImageView *)createImageViewByState:(BOOL)isSelected
{
    UIImageView *imageView = [[UIImageView alloc]init];
    
    UIImage *image = [self imageByState:isSelected starType:self.starType];
    
    [imageView setImage:image];
    
    imageView.frame = CGRectMake(0, 0, [self.class sizeOfstarByStarType:self.starType].width, [self.class sizeOfstarByStarType:self.starType].height);
    
    return imageView;
}

+ (CGSize)sizeOfstarByStarType:(LBScoreViewStarType)starType
{
    CGFloat width;
    CGFloat height;
    
    switch (starType) {
        case LBScoreViewStarTypeSmall:
        {
                width = 12;
                height = 11;
        }
            break;
        case LBScoreViewStarTypeMiddle:
        {
            width = 18;
            height = 17;
        }
            break;
        case LBScoreViewStarTypeBig:
        {
            width = 21;
            height = 20;
        }
            break;
            
        default:
            break;
    }
    
    return CGSizeMake(width, height);
}

+ (CGSize)sizeOfViewByStarType:(LBScoreViewStarType)starType
{
    CGSize newSize = [self sizeOfstarByStarType:starType];
    return CGSizeMake(((LBScoreViewMaxStarNum - 1) * LBScoreViewViewSpace +
                       LBScoreViewMaxStarNum * newSize.width),
                      newSize.height);
}

@end

@implementation LBScoreViewFrameModel

@end
